#include "./include/headers.hpp"

#include "./utils/stubborn.cpp"
#include "./utils/fsTool.cpp"
#include "./utils/ds.cpp"
#include "./utils/bufFile.cpp"
#include "./utils/execCode.cpp"

const AlgoType stdType = {
    {"dist", "sum"},
    {"initSta", "std"},
    {"sa", "std"},
    {"eng", "std"},
};

std::vector<AlgoType> seq = {
    {},
    {{"dist", "max"}},
    {{"dist", "sumExt"}},
    {{"eng", "exp"}},
    {{"eng", "xx"}},
    {{"initSta", "overlap"}},
    {{"sa", "ek"}},
    {{"sa", "rad"}},
    {{"sa", "sgc"}},
    {{"sa", "stdfakeopt"}}
};

StatData statData;
// ll execTime;
// std::string tempPath;
// std::vector<std::string> dataFiles;

// codePath dataPath dbPath tempPath
signed main(int argc, char* argv[]) {
    fprintf(stderr, "---      STAT Start       ---\n");
    printf("\
Attention: The process cannot be paused during execution!\n\
Please enter the estimated running time (in minutes): ");
    scanf("%lld", &execTime), execTime *= 60;
    assert(argc == 5), crtDir(argv[3]), crtDir(argv[4]), tempPath = argv[4];
    bufFile = std::string(argv[3]) + '/' + getCurTime() + ".dat";
    fprintf(stderr, "bufFile: %s\n", bufFile.c_str());
    dataFiles = GetFilesWithExt(argv[2], ".in");
    assert(dataFiles.size());
    for (std::string x : dataFiles) fprintf(stderr, "Find %s\n", x.c_str());

    if (bufRead(bufFile) != "") statData.deserialize(bufRead(argv[3]));
    for (AlgoType x : seq) {
        x += stdType; // Revert omitted parameters.
        if (statData.find(x) == statData.end()) statData.insert({x, {}});
    }
    for (const auto [x, y] : statData) {
        fprintf(stderr, "Task {\n");
        for (const auto [key, val] : x)
            fprintf(stderr, "    %s: %s\n", key.c_str(), val.c_str());
        fprintf(stderr, "}\n");
    }

    auto sttTime = std::chrono::steady_clock::now();
    while (true) {
        for (auto& [x, y] : statData)
        y += execCode(x), bufWrite(statData.serialize(), bufFile);
        ll elpTime = std::chrono::duration_cast<std::chrono::seconds>
        (std::chrono::steady_clock::now() - sttTime).count();
        fprintf(stderr, "Cur: %s\n", getCurTime().c_str());
        fprintf(stderr, "Ela: %lldm/%lldm\n", elpTime / 60, execTime / 60);
        if (elpTime >= execTime) break;
    }
    fprintf(stderr, "---       STAT Done       ---\n");
}
